﻿#include "../include/taskthread.h"
#include "mainwindow.h"
#include "settings.h"
SQLThread::~SQLThread()
{
	exitFlag = true;
    rarelyUsed.clear();
    frequentUsed.clear();
	usedSemaphore.release();
	freeSemaphore.release();
	wait();
}

SQLThread::SQLThread() : freeSemaphore(10), usedSemaphore(0)
{
	//10 > 10 + 3
	exitFlag = false;
    haveError = false;
	rarelyUsed.reserve(3);
	frequentUsed.reserve(10);
}

void SQLThread::run()
{
    int tryCnt = 2;// try count
	while(true) {
		while(rarelyUsed.empty() && frequentUsed.empty()) {
            usedSemaphore.acquire();//wait data coming
            if(exitFlag) {  //now exiting
                rarelyUsed.clear();
                frequentUsed.clear();
				return;
			}
		}

        if(!rarelyUsed.empty()) { //urgent cmd
			//连接数据库
			if( rarelyUsed.front().task == ConnectDb) {
                sql.setDb("test", rarelyUsed.front().user, rarelyUsed.front().passwd);//dbname is test
				if(!sql.openDb())
				{
                    emit openError(QString::fromWCharArray(L"不能连接到数据库")); //Emiting the Error signal
#if 0
					if(++tryCnt <= 3) {
                        asyncConnectDb("test", rarelyUsed.front().user, rarelyUsed.front().passwd);//Add new connect cmd into queue.
					}
					else
                    {
                        haveError = true;  //Reach the max try counts.
                        //rarelyUsed.clear();
                        //frequentUsed.clear();
                        break;
                    }
#endif
					//fail
					rarelyUsed.clear();
					frequentUsed.clear();
					freeSemaphore.release();
					usedSemaphore.release();
					continue;
				}
				else
				{					
					//(static_cast<MainWindow*>(parent()))->sqlUpdateLed(true);
					tryCnt=3;
				}

				if(!sql.createDb(rarelyUsed.front().name)) {
                    emit openError(QString::fromWCharArray(L"Create database failure"));
					break;
				}

				if(!sql.changeDb(rarelyUsed.front().name)) {
                    emit openError(QString::fromWCharArray(L"Change database failure"));
					break;
				}
				emit openSqlSuccess(); //Emiting the Error signal

			}
			else if( rarelyUsed.front().task == CreatTable)
			{
				if(! sql.creatTable(/*rarelyUsed.front().name)*/)) {
                    emit openError(QString::fromWCharArray(L"Create table failure"));
					break;
				}
			}
            else if( rarelyUsed.front().task == SelectData)
            {
#if 0
				emit getResult(sql.selectTable(rarelyUsed.front().name, cnt), cnt);
#endif
			}
			rarelyUsed.pop_front();
			freeSemaphore.release();
			continue;
		}
		//处理第二队列
		if(!frequentUsed.empty()) {
            if(sql.insertData(frequentUsed.front().table,frequentUsed.front().time, frequentUsed.front().id,
				frequentUsed.front().stationNo,frequentUsed.front().sensorNo,frequentUsed.front().data)){

			}else
			{
				ok();
			}
			frequentUsed.pop_front();
			freeSemaphore.release();
		}
	}
}

//连接数据库
void SQLThread::asyncConnectDb(const QString &db_name,const QString &user, const QString &passwd)
{
    //qDebug()<<"Is connecting Db!";
	freeSemaphore.acquire();
	rarelyUsed.push_back(SQLDataRarelyUsed(db_name,user, passwd, SQLThread::ConnectDb));
	usedSemaphore.release();

}

//创建表
void SQLThread::asyncCreatTable( QString &_table)
{
	freeSemaphore.acquire();
    rarelyUsed.push_back(SQLDataRarelyUsed(_table, SQLThread::CreatTable));
	usedSemaphore.release();

}
//表名+时间+id+采集站编号+传感器编号+数据
void SQLThread::asyncInsertData(const QString& _table,const QString& t, uint id, int stationNo, int sensorNo, float _data)
{
	//qDebug()<<"GET"<<endl;
	freeSemaphore.acquire();
    frequentUsed.push_back(SQLThread::SQLDataFrequentUsed(_table, t, id,stationNo,sensorNo, _data));
	usedSemaphore.release();
	//qDebug()<<"NOGET"<<endl;
}

void SQLThread::asyncSelectTable( QString &_table)
{
	freeSemaphore.acquire();
    rarelyUsed.push_back(SQLDataRarelyUsed(_table, SQLThread::SelectData));
	usedSemaphore.release();
}

void SQLThread::ok()
{
	asyncConnectDb(Settings::readDbName(),Settings::readDbUser(),Settings::readDbPass());
	asyncCreatTable(SQL_TABLE);
}